// Learn TypeScript:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html
const indian_names = [
    "Aarav", "Vivaan", "Aditya", "Vihaan", "Arjun", "Reyansh", "Muhammad", "Sai", "Arnav", "Ayaan",
    "Krishna", "Ishaan", "Shaurya", "Atharva", "Advait", "Pranav", "Advaith", "Aaryan", "Dhruv", "Kabir",
    "Ritvik", "Aarush", "Kian", "Darsh", "Veer", "Raj", "Mohammed", "Aryan", "Veer", "Samarth",
    "Yuvan", "Aarav", "Rudra", "Reyansh", "Siddharth", "Aaditya", "Sarvesh", "Ayaansh", "Krish", "Naksh",
    "Armaan", "Aadvik", "Ansh", "Ishaan", "Rohan", "Arhaan", "Dev", "Arjun", "Aarush", "Vivaan",
    "Adhiraj", "Anay", "Daksh", "Aarav", "Vihaan", "Arnav", "Ishaan", "Aarush", "Krishna", "Sai",
    "Arjun", "Shaurya", "Atharv", "Ayaan", "Aryan", "Rohan", "Ansh", "Aaditya", "Veer", "Samarth",
    "Rudra", "Sarvesh", "Reyansh", "Kabir", "Mohammed", "Arhaan", "Dhruv", "Kian", "Yuvan", "Raj",
    "Advait", "Ritvik", "Darsh", "Pranav", "Aadvik", "Aaryan", "Dev", "Naksh", "Armaan", "Ayaansh"
]
const betType = [200,400,600,1000]


import { LinkNode } from "../../common/script/LinkedList";
import PlayerInfo from "../../common/script/PlayerInfo";
import ProgressMgr, { Handler, ProgressHandler } from "../../common/script/ProgressMgr";
import TipsShell from "../../common/script/TipsShell";
import SpaceRocketPlayerInfoItem, { PlayerItemInfo } from "./SpaceRocketPlayerInfoItem";

const {ccclass, property} = cc._decorator;

@ccclass
export default class SpaceRocket<T> extends cc.Component {

    @property(cc.Prefab)
    ruleLayer: cc.Prefab = null;
    @property(cc.Prefab)
    tipsPrefab: cc.Prefab = null;
    @property(cc.Prefab)
    playerInfoItem: cc.Prefab = null;
    @property(cc.Node)
    bg: cc.Node = null;
    @property(cc.SpriteAtlas)
    headIconAtlas: cc.SpriteAtlas = null;
    @property(cc.Node)
    playeItemRoot: cc.Node = null;
    @property(cc.ParticleSystem)
    rocketParticle: cc.ParticleSystem = null;
    @property(cc.Node)
    rocketRoot: cc.Node = null;
    @property(cc.Node)
    rocket: cc.Node = null;
    @property(cc.Node)
    readyToLaunch: cc.Node = null;
    @property(cc.Label)
    startTimerLab: cc.Label = null;
    @property(cc.Button)
    betBtn: cc.Button = null;
    @property(cc.ToggleGroup)
    betToggleGroup: cc.ToggleGroup = null;
    @property(cc.Label)
    betAmountLab: cc.Label = null;
    @property(cc.Label)
    currentRateLab: cc.Label = null;
    @property(cc.Label)
    betBtnLab: cc.Label = null;
    @property(cc.Node)
    tookOff: cc.Node = null;




    rocketSp: cc.SpriteFrame = null;
    gameProgress = null;
    gameProgressMgr:ProgressMgr<T> = null;
    gamePayRate: number = 0;

    resultRate: number = 0;
    _currentRate: number = 0;
    get currentRate(): number {
        return this._currentRate;
    }
    set currentRate(rate: number) {
        this._currentRate = rate;
        this.currentRateLab.string = rate.toFixed(2);
    }
    
    start () {
        this.rocketSp = this.rocket.getComponent(cc.Sprite).spriteFrame;
        this.gameProgress = [
            new LinkNode(new Handler(this.enterBet,this,["enterBet"])), new LinkNode(new Handler(this.stayBet,this,["stayBet"])), new LinkNode(new Handler(this.exitBet,this,["exitBet"])),
            new LinkNode(new Handler(this.enterRunning,this,["enterRunning"])), new LinkNode(new Handler(this.stayRunning,this,["stayRunning"])), new LinkNode(new Handler(this.exitRunning,this,["exitRunning"])),
            new LinkNode(new Handler(this.enterResult,this,["enterResult"])), new LinkNode(new Handler(this.stayResult,this,["stayResult"])), new LinkNode(new Handler(this.exitResult,this,["exitResult"]))
        ]
        this.gameProgressMgr = new ProgressMgr(this.gameProgress);
        this.gameProgressMgr.startProgress();
    }

    public clickExit(event: cc.Event.EventTouch, data: any) {
        this.scheduleOnce(() => {
            cc.director.loadScene('lobby');
        }, 0)
    }
    nodePool: cc.NodePool = new cc.NodePool();
    showTip(arg) {
        let tip = cc.instantiate(this.tipsPrefab);
        tip.getComponent(TipsShell).init(this.nodePool);
        this.node.addChild(tip);
        tip.getComponent(TipsShell).showTips(arg);
    }

    public showRuleLayer() {
        let ruleLayer = cc.instantiate(this.ruleLayer);
        this.node.addChild(ruleLayer);
        ruleLayer.setPosition(0, 0);
    }
    betAmount: number = 0;
    totalBet: number = 0;
    myWinRate: number = 0;
    onToggleBtnClick(toggle: cc.Toggle, data: any) {
        this.betAmount = betType[data];
        console.log(this.betAmount,"当前投注")
    }
    onBetBtnClick(){
        if(this.gameProgressMgr.progress.current.data.args[0] == "stayRunning"){
            //this.showTip("Not enough money");
            this.myWinRate = this.currentRate;
            this.betBtn.interactable = false;
            this.betBtnLab.string = "Success";
            return;
        }
        if(this.betAmount > PlayerInfo.ins.getMoney()){
            
        }else{
            PlayerInfo.ins.subMoney(this.betAmount);
            this.totalBet += this.betAmount;
            this.betAmountLab.string = this.totalBet.toString();
            console.log(this.totalBet,"总投注");
            
        }
    }

    createPlayerItem() {
        if(Math.random() < 0.5){
            
            let headCount = this.headIconAtlas.getSpriteFrames().length;
            
            let playerItem = cc.instantiate(this.playerInfoItem);
            this.playeItemRoot.addChild(playerItem);
            playerItem.setSiblingIndex(0);
            let rate = Math.random() * this.currentRate;
            let bet = betType[Math.floor(Math.random() * betType.length)];
            let win = bet * rate;
            let data:PlayerItemInfo = {
                headIcon: this.headIconAtlas.getSpriteFrames()[Math.floor(Math.random() * headCount)],
                playerName: indian_names[Math.floor(Math.random() * indian_names.length)],
                win: win,
                bet: bet,
                rate: rate,
                
            }
            if(this.gameProgressMgr.progress.current.data.args[0] == "stayBet"){

                playerItem.getComponent(SpaceRocketPlayerInfoItem).init(data,false);
            }else{
                
                playerItem.getComponent(SpaceRocketPlayerInfoItem).init(data,true);
                this.showTookOff(data.playerName,rate)
            }
        }
        if(this.playeItemRoot.children.length > 30){
            this.playeItemRoot.children[30].destroy();
        }
        
    }

    startCreatePlayerItem(){
        this.schedule(this.createPlayerItem, 0.1, cc.macro.REPEAT_FOREVER, 0.1);

    }

    stopCreatePlayerItem() {
        this.unschedule(this.createPlayerItem);
    }

    showTookOff(name,rate) {
        let tookOff = cc.instantiate(this.tookOff.children[0]);
        let labCom = tookOff.getComponent(cc.Label);
        let str = name + " took off @" + rate.toFixed(1) + "X";
        labCom.string = str;
        this.tookOff.addChild(tookOff);
        cc.tween(tookOff)
            .by(2,{position:cc.v3(Math.random() * 600 - 300,-1000),opacity:-255})
            .call(()=>{
                tookOff.destroy();
            })
            .start();
    }

    initGame(){
        this.playeItemRoot.removeAllChildren();
        this.bg.setPosition(cc.v2(0, 0));
        this.readyToLaunch.active = true;
        this.myWinRate = 0;
        this.rocketRoot.y = -182;
        
        this.bgTween && this.bgTween.stop()
        this.totalBet = 0;
        this.betAmountLab.string = this.totalBet.toString();
        this.resultRate = Math.random() * 20;
        this.currentRate = 0;
        this.currentRateLab.string = "0.00";
        this.rocket.active = true;
        this.rocket.getComponent(cc.Sprite).spriteFrame = this.rocketSp;
        
    } 


    enterBet() {
        console.log("enterBet");
        this.initGame();
        let time = 10;
        this.startTimerLab.string = time.toString();
        this.gameProgressMgr.next();
    }

    stayBet() {
        console.log("stayBet");
        this.betBtn.interactable = true;
        this.betBtnLab.string = "Bet";
        this.startCreatePlayerItem()
        let time = 10;
        this.schedule(() => {
            time --;
            this.startTimerLab.string = time.toString();
            if(time == 0){
                this.gameProgressMgr.next();
            }
            
        },1,time-1,1);
    }
    exitBet() {
        console.log("exitBet");
        
        
        this.betBtnLab.string = "Escape";
        this.gameProgressMgr.next();
    }

    
    //------------------------------------------

    enterRunning() {
        console.log("enterRunning");
        this.readyToLaunch.active = false;
        this.rocketParticle.resetSystem();
        
        this.gameProgressMgr.next();
    }
    bgTween: cc.Tween  =null;
    stayRunning() {
        if(this.totalBet == 0){
            this.betBtn.interactable = false;
            this.betBtnLab.string = "Wait";
        }
        console.log("stayRunning");
        this.bgTween = cc.tween(this.bg)
            .to(50, {position: cc.v3(0, -500)})
            .start();
        cc.tween(this.rocketRoot)
            .by(1, {position: cc.v3(0,300,0)},{easing: "sineInOut"})
            .call(() => {
                this.bgTween.start();
                
            })
            .start();
        let self = this as SpaceRocket<T>;
        cc.tween(self)
            .to(this.resultRate, {currentRate: this.resultRate})
            .call(() => {
                this.showTip("You win " + (this.myWinRate * this.totalBet).toFixed(2));
                
                this.rocket.getComponent(cc.Animation).play();
                this.rocketParticle.stopSystem() ;
                PlayerInfo.ins.addMoney(this.myWinRate * this.totalBet);
                if(this.myWinRate == 0){
                    //this.showTip("You lose");
                    this.betBtn.interactable = false;
                    this.betBtnLab.string = "Fail";
                }else{

                    this.betBtnLab.string = "Success";   
                }
            })
            .delay(1)
            .call(() => {
                this.rocket.getComponent(cc.Animation).stop();
                this.rocket.active = false;
                this.gameProgressMgr.next();
            })
            .start();

    }
    exitRunning() {
        console.log("exitRunning");
        this.stopCreatePlayerItem();
        this.gameProgressMgr.next();
    }
    
    //------------------------------------------
    enterResult() {
        console.log("enterResult");
        this.gameProgressMgr.next();
    }

    stayResult() {
        console.log("stayResult");
        this.gameProgressMgr.next();
    
    }
    
    exitResult() {
        console.log("exitResult");

        this.scheduleOnce(() => {
            
            this.gameProgressMgr.next();
        }, 5);
    
    }

    // update (dt) {}
}
